﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

using OAuth;

using Newtonsoft.Json;

using Mr.HttpBodyWrapper;
using Mr.LinqToWeibo.SearchCriteria;

namespace Mr.LinqToWeibo
{
    internal class WeiboQueryServiceImpl
        : IWeiboQueryService
    {
        private OAuthConsumer consumer;
        private static readonly string consumerKey = "297533609";
        private static readonly string consumerSecret = "a4f6a58e864e2fe1cd15d799d48c9f8e";

        public WeiboQueryServiceImpl()
        {
            consumer = new OAuthConsumer(consumerKey, consumerSecret);
        }

        #region IWeiboQueryService Members

        private object GetObjectListBySearchCriteria<T>(WeiboApi api, ISearchCriteria criteria)
        {
            // refresh the token
            consumer.LoadAccessTokenAndSecret(this.AccessToken, this.AccessTokenSecret);

            IList<OAuthQueryParameter> queryParams = new List<OAuthQueryParameter>();
            foreach (var keyValue in api.ParamMappings)
            {
                queryParams.Add(new OAuthQueryParameter(keyValue.Key, keyValue.Value(criteria), false));
            }

            OAuthResponse response =
                consumer.InvokeAPI(
                    new Uri(api.GetApi(criteria)),
                    OAuthHttpMethod.GET,
                    new KeyValuesHttpBodyWrapper(queryParams.ToArray()));

            string result = "[]";
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                result = reader.ReadToEnd();
            }

            object list = JsonConvert.DeserializeObject<IList<T>>(result);
            return list;
        }

        public object GetObjects<T>(ISearchCriteria criteria, Scope scope)
        {
            object results = null;
            WeiboApi api = scope.GetWeiboApi();
            if (api != null)
            {
                results = this.GetObjectListBySearchCriteria<T>(api, criteria);
            }
            return results ?? null;
        }

        #endregion

        public string AccessToken { private get; set; }

        public string AccessTokenSecret { private get; set; }
    }
}
